package com.cbj.netty.handler;

import com.cbj.netty.protocol.Content;
import com.cbj.netty.protocol.Header;
import com.cbj.netty.rpc.Dispatcher;
import com.cbj.netty.util.RPCUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author Godc
 * @description 基于Http协议的服务端处理器，用于返回请求结果
 */
public class HttpServerRequestHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //http协议，上面两个handler已经被聚合，这里的msg已经被封装好，是一个HttpRequest
        FullHttpRequest request = (FullHttpRequest) msg;
        //Post请求体,也就是客户端发来的Content
        ByteBuf body = request.content();
        byte[] bytes = new byte[body.readableBytes()];
        body.readBytes(bytes);
        Content content = (Content) RPCUtil.getObject(bytes);


        //接下来就是处理请求，返回对应的结果
        // 服务名
        String name = content.getName();
        // 方法名，方法类型和参数
        String methodName = content.getMethodName();
        Class<?>[] parameterTypes = content.getParameterTypes();
        Object[] args = content.getArgs();
        // 从注册中心拿到对应的实现类
        Dispatcher dispatcher = Dispatcher.getDispatcher();
        Object o = dispatcher.get(name);
        Class<?> aClass = o.getClass();
        Object res = null;
        try {
            Method method = aClass.getMethod(methodName, parameterTypes);
            res = method.invoke(o, args);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }catch (IllegalAccessException e){
            e.printStackTrace();
        }catch (InvocationTargetException e){
            e.printStackTrace();
        }
        // 构建好返回结果的body
        Content resContent = new Content();
        resContent.setRes((String)res);
        byte[] contentMsg = RPCUtil.getBytes(resContent);
        // 封装成Http请求
        DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_0
                , HttpResponseStatus.OK
                , Unpooled.copiedBuffer(contentMsg));

        ctx.writeAndFlush(response);

    }
}
